#/usr/bin/env python
# -*- coding: UTF-8 -*-

'''
Copyright (C) 2010 dbzhang800@gmail.com
All rights reserved.

2010.07.21-2010.07.XX
''' 

import sys
import os
import platform
import shutil
import subprocess
import re
from munro_common import *

def callMunroAber(filename=""):
    '''call external program aber.exe. if filename was not expty, give the file to aber.exe'''
    callMunroPrograms("aber", filename)

class AberDatFile:
    u"""aber dat  文件的封装类，注意，
    1. dat 文件中的关键字 大小写 不区分
    2. 关键词前可以加空格或Tab
    3. 文件内允许加 // 引入注释
    4. 允许会出现空行
    """
    def __init__(self, filename):
        if not filename.lower().endswith('.dat'):
            filename += '.dat'
        self.filename = filename
        self.content = []
        if os.path.exists(filename):
            with open(filename, 'rU') as f:
                self.content = f.readlines()
        
    def save(self, filename=None):
        if not filename:
            filename = self.filename
        if not filename.lower().endswith('.dat'):
            filename += '.dat'
        with open(filename, 'w') as f:
            f.writelines(self.content)
    def _getdoublevalue(self, key):
        key = key.lower()
        for line in self.content:
            if (line.lower().lstrip().startswith(key)):
                m = re.search(r'-?([0-9]+[.]?[0-9]*|[0-9]*[.]?[0-9]+)', line)
                return m.group(0)
    def _setdoublevalue(self, key, value):
        key = key.lower()
        for i in range(len(self.content)):
            line = self.content[i]
            if (line.lower().lstrip().startswith(key)):
                self.content[i] = re.sub(r'-?([0-9]+[.]?[0-9]*|[0-9]*[.]?[0-9]+)',
                        str(value), line)
                return
    def getImagePlane(self):
        return self._getdoublevalue("Image Plane")
    def setImagePlane(self, value):
        self._setdoublevalue("Image Plane", value)
    def getBeamVoltage(self):
        return self._getdoublevalue("Beam Voltage")
    def setBeamVoltage(self, value):
        self._setdoublevalue("Beam Voltage", value)
    def getRealApertureDiameter(self):
        return self._getdoublevalue("Real Aperture Diameter")
    def setRealApertureDiameter(self, value):
        self._setdoublevalue("Real Aperture Diameter", value)
    def _findLens(self, key="Electrostatic Lens", index=1):
        u'''
        查找第index个透镜所在文件的第几行，如果查找失败则返回 -1
        '''
        base = -1
        for i in range(len(self.content)):
            line = self.content[i]
            if (line.lower().strip().startswith(key.lower())):
                base = i
                break
        if base == -1:
            return
        curIndex = 0
        for i in range(base+1, len(self.content)):
            line = self.content[i]
            if line.lstrip() and (not line.lstrip().startswith("//")):
                curIndex += 1
            if curIndex == index: # ok found
                return i
        return base
    def setELensVoltsAndName(self, volts, name, index=1):
        u""" 
        volts: 一个元组或列表，存放各个电极的电压值
        name:  静电透镜的文件名，如果后缀为 .dat或无后缀，将自动改为 .axv
        index: 第几个静电透镜，从1开始
            """

        lineindex = self._findLens("Electrostatic Lens", index)
        if lineindex == -1:
            return
        if name.lower().endswith('.dat'):
            name = name[:-4]+".axv"
        if not name.lower().endswith("axv"):
            name += ".axv"
        items = self.content[lineindex].strip().split()
        newitems = items[:3]+[str(item) for item in volts] + [name, "\n"]
        self.content[lineindex] = "      ".join(newitems)
        #print self.content[lineindex]
    def getDependFileNames(self):
        u"""
        返回该 dat 文件依赖的所有其他场的文件 axv axb ...
        """
        res = []
        for line in self.content:
            if (line.lower().lstrip().startswith("//")):
                continue
            m = re.search(r'[0-9a-zA-Z\-_.]+[.][aA][xX][a-zA-Z]', line)
            if m:
                 res.append(m.group(0))
        return res

class AberResFile:
    u"""aber res  文件的封装类，注意
    res 文件是 aber 的生成文件，无需考虑各种人为修改造成的变化
    本类只提供 只读 功能即可
    """
    def __init__(self, filename):
        if filename.lower().endswith('.dat'):
            filename = filename[:-4]+'.res'
        if not filename.lower().endswith('.res'):
            filename += '.res'
        self.filename = filename
        self.content = []
        try:
            with open(filename, 'rU') as f:
                self.content = f.readlines()
        except:
            print "Warnning: %s not found!" % filename
        #if os.path.exists(filename):
        #    with open(filename, 'rU') as f:
        #        self.content = f.readlines()
        #else:
        #    print "Warnning: %s not found!" % filename
    def getMLensExcitation(self, index=1):
        u'''读取第 index 个磁透镜的激励值(单位 Ampturns)
        '''
        key = r"MAGNETIC LENS No.\s+(\d+)\s+EXCITATION  \(Ampturns\)   =   "
        for line in self.content:
            m = re.search(key, line)
            if m and int(m.group(1))==index:
                m2 = re.search(r'(?<==)\s+-?([0-9]+[.]?[0-9]*|[0-9]*[.]?[0-9]+)', line)
                return float(m2.group(0))
        return None
    def getBeamSpotDiameter(self):
        key = r"BEAM SPOT DIAMETER  D "
        for line in self.content:
            m = re.search(key, line)
            if m:
                m2 = re.search(r'(?<==)\s+-?([0-9]+[.]?[0-9]*|[0-9]*[.]?[0-9]+)', line)
                return float(m2.group(0))
        return None
    def getDeflectionSensitivities(self, field="main"):
        u'''读取偏转灵敏度数值
        field: 可选值[main, sub]
        '''
        if field.lower() == 'main':
            key = "MAIN FIELD [.]+"    
        elif field.lower() == 'sub':
            key = "SUB FIELD [.]+"    
        else:
            return None
        #print key
        for line in self.content:
            m = re.search(key, line)
            if m:
                m2 = re.search(r'(?<==)\s+-?([0-9]+[.]?[0-9]*|[0-9]*[.]?[0-9]+)', line)
                return float(m2.group(0))
        return None

if __name__ == "__main__":
    setMunroPath(r"E:\opee pack-0.3.0.1\data\munro")
    setMunroPath(u"F:\\整理\\ziliao\\linux\\work\\munro\\munro")
    callMunroAber()
    
    aberdat = AberDatFile("rv.dat")
    print aberdat.getImagePlane()
    aberdat.setImagePlane(555.2)
    print aberdat.getImagePlane()
    print aberdat.getRealApertureDiameter()
    aberdat.setELensVoltsAndName((14000,5000,1000), "abc")
    aberdat.setRealApertureDiameter(0.2)
    aberdat.save()
    print aberdat.getDependFileNames()

    aberres = AberResFile("rv")
    print aberres.getMLensExcitation()
    print aberres.getDeflectionSensitivities('main')
    aberres = AberResFile("aberd")
    print aberres.getMLensExcitation()
    print aberres.getDeflectionSensitivities('main')


